/**
 * PJavaFXCookieCoding
 * This project is the GUI library for Processing IDE. 
 * PJavaFXCookieCoding is something like bridge for JavaFX2.0 
 * You can use native JavaFX components and UI in your processing sketches.
 * http://www.cookiecoding/pjavafx
 *
 * Copyright (C) 2011 Paul A. Orlov
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA  02111-1307  USA
 * 
 * @author      Paul A. Orlov
 * @modified    01/12/2011
 * @version     0.0.1 (0)
 */

package pjavafxcookiecoding;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import processing.core.*;

/**
 * 
 * @example FXSlider 
 * 
 * (the tag @example followed by the name of an example included in folder 'examples' will
 * automatically include the example in the javadoc.)
 *
 */

public class PJavaFXCookieCoding {
	
	// myParent is a reference to the parent sketch
	private PApplet parent;
	
	public final static String VERSION = "0.0.1";
	
	private JFrame frame;
	private Scene scene;
	private Method makeGUIEventMethod;
	private ImageView imageHouse;
	private int wayOfDraw = 0;
	
	/**
	 * a Constructor, usually called in the setup() method in your sketch to
	 * initialize and start the library.
	 * 
	 * @example FXSlider
	 * @param parent
	 */

	public PJavaFXCookieCoding(final PApplet parent) {
		this.parent = parent;
		welcome();
		
		frame = new JFrame();
		parent.registerDraw(this);
		frame.setSize(parent.width, parent.height);

		try {
			makeGUIEventMethod = parent.getClass().getMethod("makeGUI",
					new Class[] { PJavaFXCookieCoding.class });
		} catch (Exception e) {
			// no such method, or an error.. which is fine, just ignore
		}

		final JFXPanel fxPanel = new JFXPanel();
		Platform.runLater(new Runnable() {

			@Override
			public void run() {
				makeGUI();

				Group root1 = (Group) scene.getRoot();
				Image img = parent.get().getImage();
				try {
					imageHouse = new ImageView(createImage(img));
					imageHouse.setLayoutX(0);
					imageHouse.setLayoutY(0);
					root1.getChildren().add(0, imageHouse);
				} catch (IOException ex) {
					Logger.getLogger(PJavaFXCookieCoding.class.getName()).log(
							Level.SEVERE, null, ex);
				}
				fxPanel.setScene(scene);
			}
		});

		frame.add(fxPanel);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
	
	private void welcome() {
		System.out.println("PJavaFXCookieCoding 0.0.1 by Paul A. Orlov");
	}
	
	/**
	 * return the version of the library.
	 * 
	 * @return String
	 */
	public static String version() {
		return VERSION;
	}
	
	/**
	 * thanks Darryl Burke from https://forums.oracle.com/forums/thread.jspa?threadID=2236566
	 * for this code.
	 * 
	 * @param java.awt.Image
	 *          the image to convert
	 * @return javafx.scene.image.Image
	 *          the result image
	 */

	public static javafx.scene.image.Image createImage(java.awt.Image image)
			throws IOException {
		if (!(image instanceof RenderedImage)) {
			BufferedImage bufferedImage = new BufferedImage(
					image.getWidth(null), image.getHeight(null),
					BufferedImage.TYPE_INT_ARGB);
			Graphics g = bufferedImage.createGraphics();
			g.drawImage(image, 0, 0, null);
			g.dispose();

			image = bufferedImage;
		}
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		ImageIO.write((RenderedImage) image, "png", out);
		out.flush();
		ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
		return new javafx.scene.image.Image(in);
	}

	public void draw() throws IOException {
		if (wayOfDraw == 0) {
			Image img = parent.get().getImage();
			if (imageHouse != null) {
				imageHouse.setImage(createImage(img));
			}
		}
	}

	public void makeGUI() {
		if (makeGUIEventMethod != null) {
			try {
				makeGUIEventMethod.invoke(parent, new Object[] { this });
			} catch (Exception e) {
				System.err
						.println("Disabling makeGUIEventMethod for because of an error.");
				System.err.println(e);
				makeGUIEventMethod = null;
			}
		}
	}

	public void drawTwoWindows() {
		wayOfDraw = 0;
	}

	public void drawOneArtOneGUIWindow() {
		wayOfDraw = 1;
	}
	
	/**
	 * @param javafx.scene.Scene
	 *         
	 */

	public void setScene(Scene scene) {
		this.scene = scene;
	}
	
	/**
	 * @return javax.swing.JFrame
	 *          
	 */

	public JFrame getFrame() {
		return frame;
	}
}
